
import dbus
from dbus.mainloop.glib import DBusGMainLoop
import gobject
from gobject import GObject
from SimpleXMLRPCServer import SimpleXMLRPCServer
import thread
from os import path
import time

import dbus.glib
import xmlrpclib
import os
	
from threading import Thread

##################################################################################
home = os.path.expanduser("~")
home_dir = home + "/.qlive/phone"


out_ringing_file = path.join(home_dir, "out_ringing.qlive")
out_calling_file = path.join(home_dir, "out_calling.qlive")
in_ringing_file = path.join(home_dir, "in_ringing.qlive")
in_calling_file = path.join(home_dir, "in_calling.qlive")
out_hangup_file = path.join(home_dir, "out_hangup.qlive")
account_info_file = path.join(home_dir, "account_info.qlive")
##################################################################################

softphone_service = "http://localhost:9876"
connector_service = ("localhost", 9877)

class SflPhoneConnector :

	def __init__(self) :
		self.activeCalls = {}

		account = {
			"username" : "1111", 
			"Account.type" : "SIP", 
			"hostname" : "192.168.1.115", 
			"Account.alias" : "1111", 
			"password":"1111", 
			"Account.enable" : "TRUE"
		}
		self.start(account)
		

	def start(self, account) :
		session = dbus.SessionBus()

		conf_obj = session.get_object("org.sflphone.SFLphone", "/org/sflphone/SFLphone/ConfigurationManager")  
		self.conf_mgr = dbus.Interface(conf_obj ,"org.sflphone.SFLphone.ConfigurationManager")

		call_obj = session.get_object("org.sflphone.SFLphone", "/org/sflphone/SFLphone/CallManager")  
		self.call_mgr = dbus.Interface(call_obj ,"org.sflphone.SFLphone.CallManager")

		####################################
		# clear prevoius account ###########
		self.clearAccount()

		####################################
		# register event handler ###########
		self.call_mgr.connect_to_signal('incomingCall', self.on_incoming_call)
		self.call_mgr.connect_to_signal('callStateChanged', self.on_call_state_changed)

		self.call_mgr.connect_to_signal("currentSelectedCodec", self.onCurrentSelectedCodec)
		self.call_mgr.connect_to_signal("transferFailed", self.onTransferFailed)
		self.call_mgr.connect_to_signal("transferSucceded", self.onTransferSucceded)
		self.call_mgr.connect_to_signal("voiceMailNotify", self.onVoiceMailNotify)
		self.call_mgr.connect_to_signal("volumnChanged", self.onVolumnChanged)


		self.account_id = self.conf_mgr.addAccount(account).replace("/","")

		#try :
		self.conf_mgr.sendRegister(self.account_id, 1)		
		#except Error, e:
		#	print 'Send register failed  ...', e

		print "account_id =", self.account_id
		acc_file = open(account_info_file, "w")
		acc_file.write(self.account_id)
		acc_file.close()	


	def on_incoming_call(self, account, callid, to):
		print "Incoming call: " + account + ", " + callid + ", " + to
		self.activeCalls[callid] = {'Account': account, 'To': to, 'State': '' }   

		call_details = self.getCallDetails(callid)
		peer_number = call_details["PEER_NUMBER"]

		global softphone_service
		self.proxy = xmlrpclib.ServerProxy(softphone_service)
		#self.proxy.notifyIncomingCall(str(callid))
		self.proxy.notifyIncomingCall(str(peer_number), str(callid))

	def onTransferFailed(self):
		print "Transfer failed"

	def onTransferSucceded(self):
		print "Transfer succeded"

	def onVoiceMailNotify(self,account_id, count):
		print "voice_mail_notify %s %s" % (accound_id, count)

	def onVolumnChanged(self,device, value):
		print "valume %s %s" % (device, value)

	def onCurrentSelectedCodec(self,call_id, codec_name):
		print "current codec %s %s" % (call_id, codec_name)

	def on_call_state_changed(self, callid, state):
		print "Call state changed: " + callid + ", " + state
		if state == "HUNGUP":
			try:
				
				global softphone_service
				proxy = xmlrpclib.ServerProxy(softphone_service)
				proxy.setHangUp()
				

				del self.activeCalls[callid]

				## 
			except KeyError:
				print "Call " + callid + " didn't exist. Cannot delete." 

		elif state in [ "RINGING", "CURRENT", "INCOMING", "HOLD" ]:
			try:
				self.activeCalls[callid]['State'] = state 
			except KeyError, e:
				print "This call didn't exist!: " + callid + ". Adding it to the list."
				callDetails = self.getCallDetails(callid)
				self.activeCalls[callid] = {'Account': callDetails['ACCOUNTID'], 'To': callDetails['PEER_NUMBER'], 'State': state }
		elif state in [ "BUSY", "FAILURE" ]:
			try:
				del self.activeCalls[callid]
			except KeyError, e:
				print "This call didn't exist!: " + callid   

	def getCallDetails(self, callid):
		"""Return informations on this call if exists"""
		return self.call_mgr.getCallDetails(callid)

	def place_call(self, callid):
		self.call_mgr.placeCall(self.account_id, self.account_id, callid)

	def hangup(self) :
		call0 = self.activeCalls.keys()[0]
		self.call_mgr.hangUp(call0)

	def clearAccount(self):
		account_list = self.conf_mgr.getAccountList()
		for account in account_list :
			self.conf_mgr.removeAccount(account)
		return 1

	def useNewAccount(self, account):
		self.clearAccount()
		self.account_id = self.conf_mgr.addAccount(account).replace("/","")
		self.conf_mgr.sendRegister(self.account_id, 1)	

		acc_file = open(account_info_file, "w")
		acc_file.write(self.account_id)
		acc_file.close()

class Updater(Thread):
	def __init__(self, connector):
		Thread.__init__(self)
		self.connector = connector

	def updateAccount(self, data):
		account = {
			"username" : data["USERNAME"], 
			"Account.type" : "SIP", 
			"hostname" : data["SERVER"], 
			"Account.alias" : "1111", 
			"password": data["PASSWORD"], 
			"Account.enable" : "TRUE"
		}
		print account

		self.connector.useNewAccount(account)
		return 1

	def run(self):
		server = SimpleXMLRPCServer(connector_service)
		server.register_function(self.updateAccount)
		server.register_function(self.connector.clearAccount)
		print "service start @localhost 9877 forever"
		server.serve_forever()

if __name__ == "__main__" :

	gobject.threads_init()
	dbus.glib.init_threads()

	s = SflPhoneConnector()

	time.sleep(5) 
	print 'start ...'

	u = Updater(s)
	u.start()

	loop = gobject.MainLoop()
	loop.run()






